import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NzSafeAny, OnChangeType } from 'ng-zorro-antd/core/types';
import { Observable, of } from 'rxjs';

@Component({
  // eslint-disable-next-line @angular-eslint/component-selector
  selector: 'widget-entity-ref-select',
  template: `
    <nz-input-group
      style="color: rgba(0, 0, 0, 0.25)"
      [ngClass]="{ 'ant-input-disabled': nzDisabled }"
      nzSize="default"
      [nzSuffix]="dropIcon"
      (click)="select()"
    >
      <ng-template #dropIcon>
        <i nz-icon nzType="down"></i>
      </ng-template>
      <input
        nz-input
        [ngClass]="{ 'ant-input-disabled': nzDisabled }"
        [placeholder]="placeholder"
        [readonly]="true"
        [value]="displayName"
        [readonly]="nzDisabled"
      />
    </nz-input-group>
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => EntityRefSelectComponent),
      multi: true,
    },
  ],
})
export class EntityRefSelectComponent implements ControlValueAccessor {
  selectEntity;
  onChange: OnChangeType = () => {};
  @Input()
  showSelect: () => Observable<NzSafeAny> = () => of(null);
  @Input()
  getDetail: (obj: NzSafeAny) => Observable<NzSafeAny> = (obj: NzSafeAny) => of(obj);
  @Input()
  idKey: string = 'id';
  @Input()
  labelKey: string = 'name';
  @Input()
  placeholder: string = '';
  @Input()
  nzDisabled: boolean = false;

  @Output() readonly selectedValueChanged = new EventEmitter();

  public get displayName(): string {
    if (!this.selectEntity) return null;
    return this.selectEntity[this.labelKey] ?? null;
  }

  public get value(): NzSafeAny {
    if (!this.selectEntity) return null;
    return this.selectEntity[this.idKey] ?? null;
  }

  writeValue(obj: any): void {
    if (!!obj) {
      this.getDetail(obj).subscribe(entity => {
        this.selectEntity = entity;
      });
    }
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {}
  setDisabledState?(isDisabled: boolean): void {}

  select() {
    if (this.nzDisabled) return;

    this.showSelect().subscribe(backModel => {
      if (!!backModel) {
        this.selectEntity = backModel;
        this.onChange(backModel[this.idKey]);
        this.selectedValueChanged.emit(backModel);
      }
    });
  }
}
